package cn.xyz.mianshi.service.impl;

import java.util.*;
import java.util.stream.Collectors;

import cn.xyz.mianshi.vo.*;
import com.mongodb.client.MongoCursor;
import org.bson.BasicBSONObject;
import org.bson.Document;
import org.bson.types.ObjectId;
import org.mongodb.morphia.Datastore;
import org.mongodb.morphia.mapping.MappedClass;
import org.mongodb.morphia.query.Query;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import com.mongodb.BasicDBObject;
import com.mongodb.DBCollection;
import com.mongodb.DBObject;

import cn.xyz.commons.constants.KConstants;
import cn.xyz.commons.support.Callback;
import cn.xyz.commons.support.mongo.MongoOperator;
import cn.xyz.commons.utils.DateUtil;
import cn.xyz.commons.utils.StringUtil;
import cn.xyz.commons.utils.ThreadUtil;
import cn.xyz.mianshi.utils.SKBeanUtils;
import cn.xyz.repository.mongo.MongoRepository;
import cn.xyz.service.KXMPPServiceImpl;
import cn.xyz.service.KXMPPServiceImpl.MessageBean;
@Service
public class AddressBookManagerImpl extends MongoRepository<AddressBook,ObjectId> {
	@Override
	public Datastore getDatastore() {
		return SKBeanUtils.getLocalSpringBeanManager().getDatastore();
	}

	@Override
	public String getCollectionName() {
		MappedClass mappedClass = morphia.getMapper().getMappedClass(AddressBook.class);
		if(null==mappedClass)
			return null;
		return mappedClass.getCollectionName();
	}
	@Override
	public String getCollectionName(int userId) {
		int remainder=0;
		if(userId>KConstants.MIN_USERID) {
			remainder=(userId/KConstants.DB_REMAINDER.ADDRESSBOOK);
		}
		return String.valueOf(remainder);
	}


	@Override
	public Class<AddressBook> getEntityClass() {
		return AddressBook.class;
	}
	private static Config getSystemConfig(){
		return SKBeanUtils.getSystemConfig();
	}
	private static FriendsManagerImpl getFriendsManager(){
		return SKBeanUtils.getFriendsManager();
	}
	
	public List<AddressBook> uploadTelephone(User user,String deleteStr,String uploadStr,String uploadJsonStr){
//		public List<AddressBook> uploadTelephone(KSession session,String deleteStr,String uploadStr){
		List<AddressBook> books = null;
//		String telephone=session.getTelephone();
		if(!StringUtil.isEmpty(deleteStr))
			deleteByStrs(user.getUserId(), deleteStr);
		else if(!StringUtil.isEmpty(uploadStr))
			books =	uploadTelephone(user.getUserId(),user.getTelephone(), uploadStr);
		else if(!StringUtil.isEmpty(uploadJsonStr)){
			books =	uploadJsonTelephone(user.getUserId(),user.getTelephone(), uploadJsonStr);
		}
		return books;
	}
	
	/** @Description:（新版通讯录） 
	* @param userId
	* @param telephone
	* @param strs
	* @return
	**/ 
	private List<AddressBook> uploadJsonTelephone(Integer userId, String telephone, String uploadJsonStr ) {
		List<AddressBook> address = JSONObject.parseArray(uploadJsonStr, AddressBook.class);
		List<AddressBook> bookList = new ArrayList<AddressBook>();
		for(int i = 0; i < address.size(); i++){
			String repPhone = address.get(i).getToTelephone();
			String toTelephone = repPhone.replace(" ", "");
			toTelephone = toTelephone.replace("-", "");
			User user = null;
				if (0 < queryByUserIdAndToTelephone(userId, toTelephone))
					continue;// 不能让自己成为自己的通讯录好友
				if(toTelephone.equals(telephone))
					continue;
				user = SKBeanUtils.getUserManager().getUser(toTelephone);
				AddressBook saveBook = saveBook(telephone, toTelephone, user, userId, address.get(i).getToRemarkName());
				bookList.add(saveBook);
		}

		//logger.info("====>  导入完成后：   用户：  "+userId  +"  的 通讯录好友： "+JSONObject.toJSONString(bookList));
		return bookList.stream().
				filter(book -> 1==book.getRegisterEd())
				.collect(Collectors.toList());
	}
	
	/** @Description:（普通版通讯录） 
	* @param userId
	* @param telephone
	* @param strs
	* @return
	**/ 
	private List<AddressBook> uploadTelephone(Integer userId, String telephone, String strs) {
		strs = strs.replace(" ", "");
		strs = strs.replace("-", "");
		String[] array = strs.split(",");
		User user = null;
		List<AddressBook> bookList = new ArrayList<AddressBook>();
		for (String str : array) {
			if (0 < queryByUserIdAndToTelephone(userId, str))
				continue;// 不能让自己成为自己的通讯录好友
			user = SKBeanUtils.getUserManager().getUser(str);
			if(str.equals(telephone))
				continue;
			AddressBook saveBook = saveBook(telephone, str, user, userId);

			bookList.add(saveBook);

		}
		return bookList.stream().
				filter(book -> 1==book.getRegisterEd())
				.collect(Collectors.toList());
	}

	private AddressBook saveBook(String telephone, String str, User user, Integer userId, String toRemark) {
		AddressBook book = null;
		book = new AddressBook();
		book.setTelephone(telephone);
		book.setToTelephone(str);
		book.setRegisterEd(null == user ? 0 : 1);
		book.setUserId(userId);
		book.setToUserId(null == user ? null : user.getUserId());
		book.setRegisterTime(null == user ? 0 : user.getCreateTime());
		book.setToUserName(null == user ? null : user.getNickname());
		book.setToRemarkName(toRemark);
		if(null != user){
			Friends friends = getFriendsManager().getFriends(userId, user.getUserId());
			if(null == friends && 0 == getSystemConfig().getIsAutoAddressBook())
				book.setStatus(0);
			else if(null != friends && 2 == friends.getStatus())
				book.setStatus(2);
			else if(0 == getSystemConfig().getIsAutoAddressBook()){// 不自动添加
				book.setStatus(0);
			}else if (1 == getSystemConfig().getIsAutoAddressBook()) {
				book.setStatus(1);
			}
		}else {// 没有注册im
			book.setStatus(0);
		}
		/**
		 * 分表 保存
		 */
		DBObject dbObj = objectToDBObject(book);
		getDBObjectCollection(userId).insertOne(dbObj);
		if(null != user && getSystemConfig().getIsAutoAddressBook()==1){
			Map<String, String> bookMap = Maps.newConcurrentMap();
			bookMap.put("toUserId", String.valueOf(user.getUserId()));
			bookMap.put("toRemark", toRemark);
			logger.info("===》       自动添加好友：     "+JSONObject.toJSONString(bookMap));
			autofollowUser(userId, bookMap);
		}
		return book;
	}
	private AddressBook buildAddressBook(String telephone, String str, User user, Integer userId) {
		AddressBook book = new AddressBook();
		book.setTelephone(telephone);
		book.setToTelephone(str);
		book.setRegisterEd(user == null ? 0 : 1);
		book.setUserId(userId);
		book.setToUserId(user == null ? null : user.getUserId());
		book.setRegisterTime(user == null ? 0 : user.getCreateTime());
		book.setToUserName(user == null ? null : user.getNickname());
		return book;
	}
	private AddressBook saveBook(String telephone, String str, User user, Integer userId) {
		AddressBook book = null;
		book = new AddressBook();
		book.setTelephone(telephone);
		book.setToTelephone(str);
		book.setRegisterEd(user == null ? 0 : 1);
		book.setUserId(userId);
		book.setToUserId(user == null ? null : user.getUserId());
		book.setRegisterTime(user == null ? 0 : user.getCreateTime());
		book.setToUserName(user == null ? null : user.getNickname());

		/**
		 * 分表 保存
		 */
		DBObject dbObj = objectToDBObject(book);
		getDBObjectCollection(userId).insertOne(dbObj);
		return book;
	}
	
	/** @Description:（自动成为好友） 
	* @param toUserId
	* @param addressBook
	**/ 
	public void autofollowUser(Integer userId,Map<String, String> addressBook){
		SKBeanUtils.getFriendsManager().autofollowUser(userId, addressBook);
	}
	
	
	
	public void notifyBook(String telephone,Integer userId,String nickName,Long registerTime){
		System.out.println("注册时修改数据："+"telephone:"+telephone+"   toUserId:"+userId+"    nickName:"+nickName+"   registerTime:"+registerTime);
		DBCollection lastdbCollection=null;
		List<String> collectionList = getCollectionList();
		for (String dbname : collectionList) {
			lastdbCollection = getDatastore().getDB().getCollection(dbname);
			BasicDBObject lastquery=new BasicDBObject();
			lastquery.put("registerEd", 0);
			lastquery.put("toTelephone", telephone);
			BasicDBObject values=new BasicDBObject();
			values.put("registerEd", 1);
			values.put("toUserName", nickName);
			values.put("registerTime", registerTime);
			values.put("toUserId", userId);
			values.put("status", 0 == getSystemConfig().getIsAutoAddressBook() ? 0 : 1);
			lastdbCollection.update(lastquery,new BasicDBObject(MongoOperator.SET, values) ,false,true);
		}

		ThreadUtil.executeInThread(new Callback() {
			@Override
			public void execute(Object obj) {
				notifyBook(telephone);
			}
			
		});
	}
	public void notifyBook(String telephone){
		System.out.println("推送使用的电话号码："+telephone);
		//a注册   a给b发xmpp通知他我们成为通讯录好友

		List<String> collectionList = getCollectionList();
		for (String dbname : collectionList) {
			Iterator<Document> iterator = queryByToTelephone(dbname, telephone);
			try {
				while(iterator.hasNext()){
					Document dbObject =  iterator.next();
					MessageBean messageBean=new MessageBean();
					messageBean.setType(KXMPPServiceImpl.registAddressBook);
					messageBean.setFromUserId(dbObject.getInteger("toUserId").toString());
					messageBean.setFromUserName(dbObject.getString("toUserName"));
					int userId = dbObject.getInteger("userId");
					messageBean.setToUserId(userId+"");
					//messageBean.setToUserName(SKBeanUtils.getUserManager().getNickName(dbObject.getString("userId")));
					messageBean.setContent(JSONObject.toJSON(dbObject));
					try {
						KXMPPServiceImpl.getInstance().send(messageBean);
					} catch (Exception e) {
						e.printStackTrace();
					}

				}
			} finally {

			}

		}


	}
	
	private void deleteByStrs(Integer userId,String strs){
		strs=strs.replace(" ", "");
		strs=strs.replace("-", "");
		String[] deleteArray=strs.split(",");
		Document query=new Document();
		query.put("userId", userId);
		query.put("toTelephone", new BasicDBObject(MongoOperator.IN, deleteArray));

		getCollection(userId).deleteMany(query);
		//deleteByQuery(query);
	}
	
	public List<Document> findRegisterList(int userId,int pageIndex,int pageSize){
		Document query=new Document();
		query.put("registerEd", 1);
		query.put("userId",userId);

		MongoCursor<Document> iterator = getCollection(userId).find(query).iterator();
		List<Document> list=new ArrayList<>();
		Document dbObj=null;
		try {
			while (iterator.hasNext()) {
				 dbObj=iterator.next();
				 dbObj.put("toUserName", SKBeanUtils.getUserManager().getNickName((int) dbObj.get("toUserId")));
				 list.add(dbObj);
			}
		} finally {
			if(null!=iterator)
				iterator.close();
		}

		
		return list;
	}
	public Iterator<Document> queryByToTelephone(String dbName,String toTelephone){

		Document query=new Document("toTelephone", toTelephone);
		return getMongoCollection(dbName).find(query).iterator();
	}
	public long queryByUserIdAndToTelephone(Integer userId,String toTelephone){
		Document query=new Document("userId", userId);
		query.put("toTelephone", toTelephone);
		return getCollection(userId).count(query);
	}


	
	public void deleteByUserId(Integer userId,String toTelephone){
		Document query=new Document("userId", userId);
		if(!StringUtil.isEmpty(toTelephone))
			query.put("toTelephone", toTelephone);
		getCollection(userId).deleteMany(query);
	}
	
	public Iterator<Document> getAll(Integer userId,int pageIndex,int pageSize){
		Document query=new Document("userId", userId);
		return getCollection(userId).find(query).iterator();
	}
	
	public void checkAddressBook(String toTelephone,Integer toUserId){
		DBObject q=new BasicDBObject("toTelephone", toTelephone);
		List<Object> list=distinct("telephone",q);
		BasicDBObject query=null;
		BasicDBObject obj=null;
		BasicDBObject value=null;
		

		for (Object telephone : list) {

			query=new BasicDBObject("telephone", telephone.toString());
			query.append("toTelephone", toTelephone);
			obj=(BasicDBObject) findOne(query);
			if(1==obj.getInt("registerEd"))
				continue;
			query.append("registerEd", 0);
			value=new BasicDBObject("registerEd", 1);
			long registerTime= DateUtil.currentTimeSeconds();
			value.append("registerTime",registerTime);
			value.append("toUserId", toUserId);
			
		}
		
	}
	//注销手机号码
	public void writeOffUser(Integer userId){
		BasicDBObject value=new BasicDBObject("registerEd", 0);
		value.append("registerTime",0);
		updateAttributeSet("AddressBook", "userId", userId, value);
	}
	


	// 获取通讯录好友
	public List<Integer> getAddressBookUserIds(Integer userId){
		Document query=new Document("userId", userId);
		List<Document> orList=new ArrayList<Document>();
		orList.add(new Document("status", 1));
		orList.add(new Document("status", 2));
		query.append("$or", orList);
		List<Integer> resultList=new ArrayList<>();
		  Document projection=new Document("toUserId",1);
		MongoCursor<Document> iterator = getCollection(userId).find(query).projection(projection).iterator();
		Document dbObj=null;
		try {
			while (iterator.hasNext()) {
				 dbObj=iterator.next();
				 resultList.add(dbObj.getInteger("toUserId"));
			}
		} finally {
			if(null!=iterator)
				iterator.close();
		}
		return resultList;
	}



}
